Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

suite: fix SetupSubTest and TearDownSubTest execution order #1471

Conversation

linusbarth
Copy link
Contributor

Summary

The order of execution of SetupSubTest and TearDownSubTest methods was changed so that the testing context inside these methods is correct.

Changes

  • The SetupSubTest was moved to after the SetT that set the child testing context
  • The TearDownSubTest was moved to before the deferred SetT that reset the testing context (execution wise)
  • The TearDownSubTest and SetT were deferred in one block. This was fine beforehand because a panic in the TearDownSubTest would have had no influence on the "suite.SetT(oldT)". Now since a panic in the TearDownSubTest would lead to omitting the "suite.SetT(oldT)" this defer was split into two separate defers.

Motivation

There were two problems with the order of execution in the Suite.Run() method:

  • One could not access the correct testing context ("s.T()") inside the SetupSubTest and TearDownSubTest methods. If the testing context was used for e.g. assertions of mocks in the TearDownSubTest, the results would not be "attached" to the correct test in the test output.
  • The behavior was different to the order of execution for "root" tests regarding the SetupTest and TearDownTest methods (see lines 167-201). This could confuse users of the library.

Related issues

Closes #1465

@dolmen dolmen added pkg-suite Change related to package testify/suite bug labels Oct 10, 2023
suite/suite.go Outdated
if tearDownSubTest, ok := suite.s.(TearDownSubTest); ok {
tearDownSubTest.TearDownSubTest()
}
}()
Copy link
Collaborator

@dolmen dolmen Oct 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the if outside of the defer:

		if tearDownSubTest, ok := suite.s.(TearDownSubTest); ok {
			defer tearDownSubTest.TearDownSubTest()
		}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Also I took the liberty to extract the defer-function in line 102. Please note if I should revert that. I think it should not produce noticeable change.

@dolmen dolmen added the hacktoberfest-accepted Hacktoberfest label Oct 10, 2023
Copy link
Collaborator

@dolmen dolmen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also need test that enforces the order. That test should fail before your fix and succeed after.

@dolmen dolmen changed the title fix: SetupSubTest and TearDownSubTest execution order suite: fix SetupSubTest and TearDownSubTest execution order Oct 10, 2023
@linusbarth
Copy link
Contributor Author

We also need test that enforces the order. That test should fail before your fix and succeed after.

done

@dolmen
Copy link
Collaborator

dolmen commented Oct 15, 2023

@linusbarth Please drop the last commit (merge commit). Use git rebase instead.

@dolmen dolmen force-pushed the fix-setup-and-teardown-subtest-execution-order branch from 4f8dd94 to 7d0eaf9 Compare October 15, 2023 22:35
@@ -259,10 +259,14 @@ func (suite *SuiteTester) TestSubtest() {

func (suite *SuiteTester) TearDownSubTest() {
suite.TearDownSubTestRunCount++
// We should get the *testing.T for the test that is to be torn down
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this comment as 3rd argument of Contains below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

func (suite *SuiteTester) SetupSubTest() {
suite.SetupSubTestRunCount++
// We should get the *testing.T for the test that is to be set up
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this comment as 3rd argument of Contains below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@linusbarth linusbarth force-pushed the fix-setup-and-teardown-subtest-execution-order branch 3 times, most recently from 33e63d9 to c46c72b Compare October 16, 2023 00:59
There were two problems with the order of execution in the Suite.Run() method:
- One could not access the correct testing context ("s.T()") inside the SetupSubTest and TearDownSubTest methods. If the testing context was used for e.g. assertions of mocks in the TearDownSubTest, the results would not be "attached" to the correct test in the test output.
- The behavior was different to the order of execution for "root" tests (see lines 167-201) regarding the SetupTest and TearDownTest methods. This could confuse users of the library.

Also the logic to be deferred was joined together. This was fine beforehand because a panic in the TearDownSubTest would have had no influence on the "suite.SetT(oldT)". Now since a panic in the TearDownSubTest would lead to omitting the "suite.SetT(oldT)" this defer was split into two separate defers.
dolmen
dolmen previously approved these changes Oct 16, 2023
Copy link

@tomhutch tomhutch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I'd be really happy to see this fix get in.

@@ -259,10 +259,12 @@ func (suite *SuiteTester) TestSubtest() {

func (suite *SuiteTester) TearDownSubTest() {
suite.TearDownSubTestRunCount++
suite.Contains(suite.T().Name(), "subtest", "We should get the *testing.T for the test that is to be torn down")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating the test suite attributes here and performing assertions alongside the others in the main test body will be more consistent with the current testing setup:

testify/suite/suite_test.go

Lines 154 to 172 in ac5cd69

SetupSuiteRunCount int
TearDownSuiteRunCount int
SetupTestRunCount int
TearDownTestRunCount int
TestOneRunCount int
TestTwoRunCount int
TestSubtestRunCount int
NonTestMethodRunCount int
SetupSubTestRunCount int
TearDownSubTestRunCount int
SuiteNameBefore []string
TestNameBefore []string
SuiteNameAfter []string
TestNameAfter []string
TimeBefore []time.Time
TimeAfter []time.Time

See this for reference:
https://github.com/stretchr/testify/pull/1393/files#diff-ca4ffdb7050ad570420ac5682fefad8481384709c2884051cd57071283ce9ca4

Copy link
Contributor Author

@linusbarth linusbarth Oct 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your review! You're right, that is more consistent. I mostly just copied your referenced testing code now into my branch.

suite/suite.go Show resolved Hide resolved
This fix adds panic handling for subtests which will achieve:
- subtests will fail for the correct test context when panicking
- the test execution is not stopped; the next subtest will be executed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug hacktoberfest-accepted Hacktoberfest pkg-suite Change related to package testify/suite
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Test name refers to parent test name in TearDownSubTest
5 participants